<?php
class Zen_List_Select {
	
	/**
	 * Таблица типа Zend_Db
	 * @var Zend_Db
	 */
	private $table;
	
	/**
	 * Столбцы,значения которых нам нужно получить
	 * @var array
	 */
	private $columns = '*';
	/**
	 * Количество элементов на странице
	 * @var int
	 */
	private $limit = 0;
	
	/**
	 * Начать со страницы
	 * @var int
	 */
	private $page = 1;
	
	/**
	 * Общее количество страниц
	 * @var int
	 */
	private $pagecount;
	
	/**
	 * Общее количество записей
	 * @var int
	 */
	private $totalcount;
	
	/**
	 * Сортировка по полю
	 * пример date DESC
	 * @var string
	 */
	private $order = false;
	
	/**
	 * Просчитывать или нет пагинацию,
	 * при просчете используются больше ресурсов
	 * @var boolean
	 */
	private $paging = false;
	
	/**
	 * Основной параметр отбора
	 * @var string|boolean
	 */
	private $where = false;
	
	/**
	 * Основной параметр группировки
	 * @var string|boolean
	 */
	private $group_by = false;
	
	/**
	 * Привязки к другим таблицам
	 * @var string|boolean
	 * Пример:
	 * 
	 * array(
	 * 		'field' => array( 'table' => 'ClassName|TableName', 'relfield' => 'RelField', 'columns' => null ),
	 * )
	 * select()->setRelations(array('owner_id'=>array('table'=>'client','relfield'=>'id','columns'=>array('id','name'))))->getData();
	 */
	private $relations = false;
	
	private $distinct = false;
	
	protected function setTotalcount($totalcount) {
		if ($this->limit > 0) {
			$this->pagecount = ceil ( ($totalcount) / $this->limit );
		} else {
			$this->pagecount = 1;
		}
		$this->totalcount = $totalcount;
	}
	
	protected  function countpages($select) {
		$adapder = new Zend_Paginator_Adapter_DbTableSelect ( $select );
		$this->setTotalcount ( $adapder->count () );
	}
	
//INFO
	public function getTableName() {
		$table = $this->table;
		$info = $table->info ();
		return ($info ['name']);
	}
	
	public function getOne($where = false) {
		$res = $this->getData($where);
		if($res){
			return $res[0];
		}else{
			return false;
		}
	}
	
	public function getData($where = false) {
		
		$columns = $this->getColumns ();
		$select = $this->table->select ()->from ( $this->table, $columns );
		if ($this->getLimit() >= 1)
			$select->limitPage ( $this->getPage(), $this->getLimit() );
		
		if ($this->getWhere()) {
			$select->where ( $this->getWhere() );
		
		} else {
			if ($where) {
				$select->where ( $where );
			}
		}
		
		if ($this->getGroupBy()) {
			$select->group($this->getGroupBy());
		}
		
		if ($this->getOrder()) {
			$select->order ( $this->getOrder());
		}
		
		if ($this->getDistinct()) {
			$select->distinct();
		}
		
		if (($this->getPaging() != false) && ($this->getTotalcount() == 0)) {
			$this->countpages ( $select );
		}
		
		$select = $this->prepareRelations($select);
		
		$res = $select->query ()->fetchAll ();
		
		return $res;
	}
	/**
	 * @return the $table
	 */
	public function getTable() {
		return $this->table;
	}
	
	/**
	 * @return the $columns
	 */
	public function getColumns() {
		return $this->columns;
	}
	
	/**
	 * @return the $limit
	 */
	public function getLimit() {
		return $this->limit;
	}
	
	/**
	 * @return the $page
	 */
	public function getPage() {
		return $this->page;
	}
	
	/**
	 * @return the $pagecount
	 */
	public function getPagecount() {
		return $this->pagecount;
	}
	
	/**
	 * @return the $totalcount
	 */
	public function getTotalcount() {
		return $this->totalcount;
	}
	
	/**
	 * @return the $order
	 */
	public function getOrder() {
		return $this->order;
	}
	
	/**
	 * @return the $paging
	 */
	public function getPaging() {
		return $this->paging;
	}
	
	/**
	 * @return the $where
	 */
	public function getWhere() {
		return $this->where;
	}
	
	/**
	 * @return the group_by
	 */
	public function getGroupBy() {
		return $this->group_by;
	}
	
	/**
	 * @return the relations
	 */
	public function getRelations() {
		return $this->relations;
	}
	
	/**
	 * @return bool $distinct
	 */
	public function getDistinct() {
		return $this->distinct;
	}
	
	/**
	 * @param Zend_Db_Table $table
	 */
	public function setTable($table) {
		if ($table instanceof Zend_Db_Table_Abstract) {
			$this->table = $table;
		} else {
			if (is_string ( $table )) {
				$this->table = new Zend_Db_Table ( $table );
			}
		}
		return $this;
	}
	
	/**
	 * @param array $columns
	 */
	public function setColumns($columns) {
		$this->columns = $columns;
		return $this;
	}
	
	/**
	 * @param int $limit
	 */
	public function setLimit($limit) {
		$this->limit = $limit;
		return $this;
	}
	
	/**
	 * @param int $page
	 */
	public function setPage($page) {
		$this->page = $page;
		return $this;
	}
	
	/**
	 * @param int $pagecount
	 */
	public function setPagecount($pagecount) {
		$this->pagecount = $pagecount;
		return $this;
	}
	
	/**
	 * @param string $order
	 */
	public function setOrder($order) {
		$this->order = $order;
		return $this;
	}
	
	/**
	 * @param boolean $paging
	 */
	public function setPaging($paging) {
		$this->paging = $paging;
		return $this;
	}
	
	/**
	 * @param string $where
	 */
	public function setWhere($where) {
		$this->where = $where;
		return $this;
	}
	
	public function setGroupBy($group_by) {
		$this->group_by = $group_by;
		return $this;
	}
	
	/**
	 * @param string $relations
	 */
	public function setRelations($relations) {
		$this->relations = $relations;
		return $this;
	}
	
	/**
	 * @param bool $distinct
	 */
	public function setDistinct($distinct) {
		$this->distinct = $distinct;
		return $this;
	}

	private function prepareRelations($select) {
		if (! $this->getRelations()) return $select;
		$relations = $this->getRelations();
		foreach ($relations as $this_field => $relation) {
			$join_table = $relation['table'];
			if ($join_table instanceof Zend_Db_Table_Abstract) {
				$join_table = $join_table->info(Zend_Db_Table_Abstract::NAME);
			} 
			$this_table = $this->getTableName();
			$join_field = $relation['relfield'];
			$rel_fields = array();
			if ( isset($relation['columns']) && is_array($relation['columns'])) {
				foreach ( $relation['columns'] as $column ) {
					$rel_fields["$join_table.$column"] = "$join_table.$column";
				}
			}
			$select->joinLeft(
				array($join_table),
                "$join_table.$join_field = $this_table.$this_field",
                $rel_fields
            );
		}
		$select->setIntegrityCheck(false);
		return $select;
	}
	
}